概 述

这是一款具有IP65级防护等级的200KHZ高频型超声波测距传感器,采用标准ModbusRTU协议的RS485通信接口,具有高度的通信可靠性,并且传感器的从机地址及串口参数都可以根据实际情况作修改,因此可以方便快速的连接到各种工控主机,非常方便上手使用。该传感器具有灵活的温度补偿功能,用户可以根据实际需求选择外部温度补偿或板载温度补偿功能来避免环境温度对测量结果造成的较大影响。传感器采用了高频率,高稳定性的超声波换能器,测试平整反射面的有效测距范围为100mm – 1500mm,精度为1mm,误差约为±1%。相对于一般的工作在40KHZ声学频率的超声波测距传感器,该测距传感器的测量精度更高,同时具有较短的测量周期,因此该传感器非常适合高精度,快速响应的测距应用。另外传感器内置噪声等级评估功能,能够在复杂的场景中实现自适应测距,用户也可以通过获取噪声等级来优化传感器的工况,从而获得最高精度的测量数据。

技术参数

  • 工作电压:DC 7-15V
  • 最大瞬时电流:350mA
  • 有效量程:100-1500mm
  • 距离分辨率:0.1mm
  • 测量精度:1mm
  • 距离误差:±0.1%
  • 温度分辨率:0.1℃
  • 温度误差:±1℃
  • 测量频率:30Hz
  • 工作温度:-20℃~+80℃
  • 传感器声学频率:200KHz±4%
  • 传感器方向角:12°±2°(-6dB)
  • 防护等级:IP65
  • 通信接口:RS485

接口说明

接口及尺寸示意图


模块接口线序如下:

1、橙 ------ VCC

2、黑 ------ GND

3、蓝 ------ RS485-B

4、白 ------ RS485-A

寄存器说明

地址 数量 名称 读写 数据范围 默认值 数据说明
0x00 1 模块PID寄存器 R 0x0000-0xFFFF 0x0002 该位用于产品校验[可实现模块类型的检测]
0x01 1 模块VID寄存器 R 0x0000-0xFFFF 0x0010 该位用于版本校验[0x0010表示V0.0.1.0]
0x02 1 模块地址寄存器 R/W 0x0001-0x00F7 0x000C [传感器地址未知时,可通过广播地址0x00做写入寄存器操作,此时传感器不会有数据输出]
断电保存,重启后生效
0x03 1 串口参数控制寄存器1 R/W 0x0000-0xFFFF 0x0005 模块波特率
0x0001---2400
0x0003---9600
0x0004---14400
0x0005---19200
0x0006---38400
0x0007---57600
0x0008---115200
Other----115200
断电保存,重启后生效
0x04 1 串口参数控制寄存器2 R/W 0x0000-0xFFFF 0x0001 模块校验位H    停止位L
0x00--无        0x00--0.5Byte
0x01--Even      0x01--1Byte
0x02--Odd      0x02--1.5Byte
Other--无       0x03--2Byte
                Other--1Byte        
断电保存,重启后生效
0x05 1 距离寄存器 R 0x0000-0xFFFF 0xFFFF 模块测得的距离值LSB代表0.1mm
0x06 1 板载温度数据寄存器 R 0x0000-0xFFFF 0x0000 板载温度传感器测得的温度数据LSB代表0.1摄氏度(有符号数)
0x07 1 外部温度补偿数据寄存器 R/W 0x0000-0xFFFF 0x0000 写入环境温度数据到该寄存器用于外部温度补偿LSB代表0.1摄氏度(有符号数)
0x08 1 控制寄存器 R/W 0x0000-0xFFFF 0x0004 bit0
0-使用板载温度补偿功能
1-使用外部温度补偿功能(需用户写入温度数据至外部温度补偿数据寄存器)
bit1
0-开启温度补偿功能
1-关闭温度补偿功能
bit2
0-自动测距
1-被动测距
bit3
被动模式下,向该位写入1,传感器将完成一次测距,测距完成后(约30ms)可从距离寄存器读出距离值,自动测距模式下该位保留。该位置1后将自动清0
断电保存,立即生效
0x09 1 电源噪声等级寄存器 R 0x0000-0x0A 0x0000 0x0000-0x000A对应噪声等级0-10
该参数能够反映供电电源以及环境对传感器的影响程度。噪声等级越小,传感器得到的距离值将更精准。

SEN0358寄存器读写示例

准备

  • 硬件
    • 1 x Arduino Leonardo控制板(RS485转TTL需要占用一个串口,推荐使用两个串口以上的设备,示例中用的是Arduino Leonardo,由于Arduino Modbus协议会占用较大内存,所以建议使用Arduino Mega2560控制板
    • 1 x Arduino TTL转485扩展板
    • 1 x 直流电源
    • 1 x USB数据线(USB数据线一端连接Arduino板USB口,另一端连接至电脑USB口)
  • 软件
    • Arduino IDE, 点击下载Arduino IDE
    • 在IDE中打开Library Manager(Ctrl+Shift+I),找到并安装ArduinoModbus和ArduinoRS485两个库

库安装

  • 硬件接线示意图
测距演示

读取测量距离示例

/**************************************************************************************************************
     This code tests the range finder function of the URM14 ultrasonic sensor
     @ author : roker.wang@dfrobot.com
     @ data   : 11.08.2020
     @ version: 1.0
**************************************************************************************************************/
#include <ArduinoModbus.h>
#include <ArduinoRS485.h>

#define   SLAVE_ADDR                ((uint16_t)0x0C)

#define   TEMP_CPT_SEL_BIT          ((uint16_t)0x01)
#define   TEMP_CPT_ENABLE_BIT       ((uint16_t)0x01 << 1)
#define   MEASURE_MODE_BIT          ((uint16_t)0x01 << 2)
#define   MEASURE_TRIG_BIT          ((uint16_t)0x01 << 3)


typedef enum{ 
  ePid,
  eVid,
  eAddr,
  eComBaudrate,
  eComParityStop,
  eDistance,
  eInternalTempreture,
  eExternTempreture,
  eControl,
  eNoise
}eRegIndex_t;//Sensor register index

/*
 *@brief Read data from holding register of client
 *
 *@param addr : Address of Client
 *@param reg: Reg index
 *@return data if execute successfully, false oxffff.
 */
uint16_t readData(uint16_t addr, eRegIndex_t reg)
{
  uint16_t data;
  if (!ModbusRTUClient.requestFrom(addr, HOLDING_REGISTERS, reg, 1)){
    Serial.print("failed to read registers! ");
    Serial.println(ModbusRTUClient.lastError());
    data = 0xffff;
  }else{
    data =  ModbusRTUClient.read();
  }
  return data;
}

/*
 *@brief write data to holding register of client 
 *
 *@param addr : Address of Client
 *@param reg: Reg index
 *@param data: The data to be written
 *@return 1 if execute successfully, false 0.
 */
uint16_t writeData(uint16_t addr, eRegIndex_t reg, uint16_t data)
{
  if (!ModbusRTUClient.holdingRegisterWrite(addr, reg, data)){
    Serial.print("Failed to write coil! ");
    Serial.println(ModbusRTUClient.lastError());
    return 0;
  }else
    return 1;
}

float  dist;
volatile uint16_t cr = 0;
void setup() {
  ModbusRTUClient.begin(19200);
  Serial.begin(9600);
  cr |= MEASURE_MODE_BIT;//Set bit2 , Set to trigger mode
  cr &= ~(uint16_t)TEMP_CPT_SEL_BIT;//Select internal temperature compensation
  cr &= ~(uint16_t)TEMP_CPT_ENABLE_BIT;//enable temperature compensation
  writeData(SLAVE_ADDR, eControl, cr); //Writes the setting value to the control register
  delay(100);
}

void loop() {
  cr |= MEASURE_TRIG_BIT;//Set trig bit
  writeData(SLAVE_ADDR, eControl, cr); //Write the value to the control register and trigger a ranging
  delay(300);//Delay of 300ms(minimum delay should be greater than 30ms) is to wait for the completion of ranging
  dist = (float)readData(SLAVE_ADDR, eDistance) / 10;//Read distance register, one LSB is 0.1mm
  
  Serial.print("distance = ");
  Serial.print(dist, 1);
  Serial.println("mm");
}
测距演示

读取板载温度示例

/**************************************************************************************************************
     This code tests the temperature measurement function of the URM14 ultrasonic sensor
     @ author : roker.wang@dfrobot.com
     @ data   : 11.08.2020
     @ version: 1.0
     RX(TTL-RS485转接板) -> TX1/D1 (Arduino Leonardo)  TX(TTL-RS485转接板)-> RX1/D0 (Arduino Leonardo)
**************************************************************************************************************/
#include <ArduinoModbus.h>
#include <ArduinoRS485.h>

#define   SLAVE_ADDR                ((uint16_t)0x0C)

#define   TEMP_CPT_SEL_BIT          ((uint16_t)0x01)
#define   TEMP_CPT_ENABLE_BIT       ((uint16_t)0x01 << 1)
#define   MEASURE_MODE_BIT          ((uint16_t)0x01 << 2)
#define   MEASURE_TRIG_BIT          ((uint16_t)0x01 << 3)

typedef enum{ 
  ePid,
  eVid,
  eAddr,
  eComBaudrate,
  eComParityStop,
  eDistance,
  eInternalTempreture,
  eExternTempreture,
  eControl,
  eNoise
}eRegIndex_t;//Sensor register index


/*
 *@brief Read data from holding register of client
 *
 *@param addr : Address of Client
 *@param reg: Reg index
 *@return data if execute successfully, false oxffff.
 */
uint16_t readData(uint16_t addr, eRegIndex_t reg)
{
  uint16_t data;
  if (!ModbusRTUClient.requestFrom(addr, HOLDING_REGISTERS, reg, 1)){
    Serial.print("failed to read registers! ");
    Serial.println(ModbusRTUClient.lastError());
    data = 0xffff;
  }else{
    data =  ModbusRTUClient.read();
  }
  return data;
}

/*
 *@brief write data to holding register of client 
 *
 *@param addr : Address of Client
 *@param reg: Reg index
 *@param data: The data to be written
 *@return 1 if execute successfully, false 0.
 */
uint16_t writeData(uint16_t addr, eRegIndex_t reg, uint16_t data)
{
  if (!ModbusRTUClient.holdingRegisterWrite(addr, reg, data)){
    Serial.print("Failed to write coil! ");
    Serial.println(ModbusRTUClient.lastError());
    return 0;
  }else
    return 1;
}

void setup() {
  Serial.begin(9600);
  ModbusRTUClient.begin(19200);
}

volatile float temp;
void loop() {
  temp =  (float)readData(SLAVE_ADDR, eInternalTempreture) / 10.0;//Read the temperature register, one LSB is 0.1℃
  Serial.print("internal tempreture = ");
  Serial.print(temp, 1);
  Serial.println("C");
  delay(500);
}
测温演示

修改模块地址

/**************************************************************************************************************
     This code tests the address modification function of the URM14 ultrasonic sensor
     @ author : roker.wang@dfrobot.com
     @ data   : 11.08.2020
     @ version: 1.0
     RX(TTL-RS485转接板) -> TX1/D1 (Arduino Leonardo)  TX(TTL-RS485转接板)-> RX1/D0 (Arduino Leonardo)
**************************************************************************************************************/
#include <ArduinoModbus.h>
#include <ArduinoRS485.h>

#define   PUBLIC_ADDR               ((uint16_t)0x00)
#define   SLAVE_ADDR                ((uint16_t)0x0C)

#define   TEMP_CPT_SEL_BIT          ((uint16_t)0x01)
#define   TEMP_CPT_ENABLE_BIT       ((uint16_t)0x01 << 1)
#define   MEASURE_MODE_BIT          ((uint16_t)0x01 << 2)
#define   MEASURE_TRIG_BIT          ((uint16_t)0x01 << 3)

typedef enum{ 
  ePid,
  eVid,
  eAddr,
  eComBaudrate,
  eComParityStop,
  eDistance,
  eInternalTempreture,
  eExternTempreture,
  eControl,
  eNoise
}eRegIndex_t;//Sensor register index

/*
 *@brief Read data from holding register of client
 *
 *@param addr : Address of Client
 *@param reg: Reg index
 *@return data if execute successfully, false oxffff.
 */
uint16_t readData(uint16_t addr, eRegIndex_t reg)
{
  uint16_t data;
  if (!ModbusRTUClient.requestFrom(addr, HOLDING_REGISTERS, reg, 1)){
    Serial.print("failed to read registers! ");
    Serial.println(ModbusRTUClient.lastError());
    data = 0xffff;
  }else{
    data =  ModbusRTUClient.read();
  }
  return data;
}

/*
 *@brief write data to holding register of client 
 *
 *@param addr : Address of Client
 *@param reg: Reg index
 *@param data: The data to be written
 *@return 1 if execute successfully, false 0.
 */
uint16_t writeData(uint16_t addr, eRegIndex_t reg, uint16_t data)
{
  if (!ModbusRTUClient.holdingRegisterWrite(addr, reg, data)){
    Serial.print("Failed to write coil! ");
    Serial.println(ModbusRTUClient.lastError());
    return 0;
  }else
    return 1;
}

void setup() {
  Serial.begin(9600);
  ModbusRTUClient.begin(19200);
  delay(3000);
}
volatile uint16_t newAddr, res;
void loop() {
  newAddr = 0x11;
  res = writeData(PUBLIC_ADDR, eAddr, newAddr);//Writes the new address value to the register
  Serial.print("The device address has been modified as ");

  Serial.print(newAddr);
  Serial.println(".please reset the device!");
  while (1);
}
修改模块地址演示

修改模块波特率

/**************************************************************************************************************
     This code tests the baudrate modification function of the URM14 ultrasonic sensor
     @ author : roker.wang@dfrobot.com
     @ data   : 11.08.2020
     @ version: 1.0
     RX(TTL-RS485转接板) -> TX1/D1 (Arduino Leonardo)  TX(TTL-RS485转接板)-> RX1/D0 (Arduino Leonardo)
**************************************************************************************************************/
#include <ArduinoModbus.h>
#include <ArduinoRS485.h>

#define   BAUDRATE_DEFAULT          ((uint32_t)19200)
#define   SLAVE_ADDR                ((uint16_t)0x0C)

#define   TEMP_CPT_SEL_BIT          ((uint16_t)0x01)
#define   TEMP_CPT_ENABLE_BIT       ((uint16_t)0x01 << 1)
#define   MEASURE_MODE_BIT          ((uint16_t)0x01 << 2)
#define   MEASURE_TRIG_BIT          ((uint16_t)0x01 << 3)

typedef enum{ 
  ePid,
  eVid,
  eAddr,
  eComBaudrate,
  eComParityStop,
  eDistance,
  eInternalTempreture,
  eExternTempreture,
  eControl,
  eNoise
}eRegIndex_t;//Sensor register index

/*
 *@brief Read data from holding register of client
 *
 *@param addr : Address of Client
 *@param reg: Reg index
 *@return data if execute successfully, false oxffff.
 */
uint16_t readData(uint16_t addr, eRegIndex_t reg)
{
  uint16_t data;
  if (!ModbusRTUClient.requestFrom(addr, HOLDING_REGISTERS, reg, 1)){
    Serial.print("failed to read registers! ");
    Serial.println(ModbusRTUClient.lastError());
    data = 0xffff;
  }else{
    data =  ModbusRTUClient.read();
  }
  return data;
}

/*
 *@brief write data to holding register of client 
 *
 *@param addr : Address of Client
 *@param reg: Reg index
 *@param data: The data to be written
 *@return 1 if execute successfully, false 0.
 */
uint16_t writeData(uint16_t addr, eRegIndex_t reg, uint16_t data)
{
  if (!ModbusRTUClient.holdingRegisterWrite(addr, reg, data)){
    Serial.print("Failed to write coil! ");
    Serial.println(ModbusRTUClient.lastError());
    return 0;
  }else
    return 1;
}

void setup() {
  Serial.begin(9600);
  ModbusRTUClient.begin(BAUDRATE_DEFAULT);
  delay(3000);
}
volatile uint16_t baudrateIndex, res;
void loop() {
  
  baudrateIndex = 3;       //0x0001---2400   0x0002---4800 0x0003---9600   0x0004---14400
                           //0x0005---19200  0x0006---38400 0x0007---57600 0x0008---115200 Other----115200
  res = writeData(SLAVE_ADDR, eComBaudrate, baudrateIndex);//Writes the new baud rate value to the corresponding register
  if (res)
    Serial.print("The baudrate has been modified as 9600.please reset the device!");
  while (1);
}
修改模块波特率演示

探测角度及灵敏度说明

超声波传感器的物理特性决定了其实际具有不规则的探测区域,因此超声波测距传感器的探测角度难以被准确的定义。而该高声学频率超声波测距传感器模块的探测区域及灵敏度对比其它超声波传感器是很小的。我们分别使用了2种参考目标障碍物对多样本产品进行了测试,对应目标的参照检测区域如下图示:

常见问题

1、Arduino Modbus库如何修改串口号

2、如有疑问,欢迎通过qq或者论坛联系我们!
更多问题及有趣的应用,可以 访问论坛 进行查阅或发帖。

更多

DFshopping_car1.png [DFRobot商城购买链接]